import os
import socket
import threading
import urllib2
from xml.dom.minidom import parseString

import orpg.plugindb # VEG
import orpg.pluginhandler
from orpg.orpgCore import *
from orpg.orpg_wx import *
from cherrypy.cpg import server

 # VEG (march 21, 2007): Now remembers your last web server on/off setting

class Plugin(orpg.pluginhandler.PluginHandler):
    # Initialization subroutine.
    #
    # !self : instance of self
    # !openrpg : instance of the the base openrpg control
    def __init__(self, plugindb, parent):
        orpg.pluginhandler.PluginHandler.__init__(self, plugindb, parent)

        # The Following code should be edited to contain the proper information
        self.name = 'CherryPy Web Server'
        self.author = 'Dj Gilcrease'
        self.help = 'This plugin turns OpenRPG into a Web server\n'
        self.help += 'allowing you to host your map and mini files localy'

        #You can set variables below here. Always set them to a blank value in this section. Use plugin_enabled
        #to set their proper values.
        self.isServerRunning = False
        self.host = None

    def plugin_menu(self):
        self.menu = wx.Menu()
        self.toggle = self.menu.AppendCheckItem(wx.ID_ANY, 'On')
        self.topframe.Bind(wx.EVT_MENU, self.cherrypy_toggle, self.toggle)

    def cherrypy_toggle(self, evt):
        if self.toggle.IsChecked():
            self.on_cherrypy("on")
        else:
            self.on_cherrypy("off")

    def plugin_enabled(self):
        self.host = parseString(
            urllib2.urlopen("http://orpgmeta.appspot.com/myip").read()
        ).documentElement.getAttribute("ip")

        self.port = self.plugindb.GetString("xxcherrypy", "port", None) or '8080'
        self.plugin_addcommand('/cherrypy', self.on_cherrypy,
                               '[on | off | port | status] - This controls the CherryPy Web Server')

        self.cherryhost = 'http://' + self.host + ':' + str(self.port) + '/webfiles/'
        open_rpg.add_component("cherrypy", self.cherryhost)

    def plugin_disabled(self):
        self.plugin_removecmd('/cherrypy')

        if self.isServerRunning:
            server.stop()
            self.webserver.join()
            self.isServerRunning = False

        open_rpg.del_component("cherrypy")

    def on_cherrypy(self, cmdargs):
        args = cmdargs.split(None,-1)

        if len(args) == 0 or args[0] == 'status':
            self.chat.InfoPost("CherryPy Web Server is currently running: " + str(self.isServerRunning))
            self.chat.InfoPost("CherryPy Web Server address is: " + self.cherryhost)

        elif args[0] == 'on' and not self.isServerRunning:
            self.webserver = threading.Thread(target=self.startServer)
            self.webserver.daemon = True
            self.webserver.start()
            self.plugindb.SetString("xxcherrypy", "auto_start", "on")

        elif args[0] == 'off' and self.isServerRunning:
            server.stop()
            self.webserver.join()
            self.chat.InfoPost("CherryPy Web Server is now disabled")
            self.plugindb.SetString("xxcherrypy", "auto_start", "off")

        elif args[0] == 'port':
            self.port = args[1]
            self.plugindb.SetString("xxcherrypy", "port", self.port)
            self.cherryhost = 'http://' + self.host + ':' + str(self.port) + '/webfiles/'
            open_rpg.add_component("cherrypy", self.cherryhost)

            if self.isServerRunning:
                server.stop()
                self.webserver.join()
                self.on_cherrypy("on")



    def startServer(self):
        try:
            if not self.host:
                raise AttributeError("Invalid IP address.<br />"
                                     "This error means you are behind a router "
                                     "or some other form of network that is "
                                     "giving you a Privet IP only (ie. "
                                     "192.168.x.x, 10.x.x.x, 172.16 - 32.x.x)")

            self.isServerRunning  = True
            self.toggle.Check(True)
            self.on_cherrypy("")

            server.start(configMap =
                        {'staticContentList': [
                            ['', orpg.dirpath.dir_struct["user"] + 'webfiles/'],
                            ['webfiles', orpg.dirpath.dir_struct["user"] + 'webfiles/'],
                            ['Textures', orpg.dirpath.dir_struct["user"] + 'Textures/'],
                            ['Maps', orpg.dirpath.dir_struct["user"] + 'Maps/'],
                            ['Miniatures', orpg.dirpath.dir_struct["user"] + 'Miniatures']
                        ],
                        'socketPort': int(self.port),
                        'logToScreen': 0,
                        'logFile': orpg.dirpath.dir_struct["user"] + 'webfiles/log.txt',
                        'sessionStorageType': 'ram',
                        'threadPool': 10,
                        'sessionTimeout': 30,
                        'sessionCleanUpDelay': 30})
        except AttributeError, e:
            self.chat.InfoPost("FAILED to start server!")
            self.chat.InfoPost(str(e))

        self.isServerRunning  = False
        self.toggle.Check(False)
